package com.enjoyor.soa.traffic.core.tpcms.service.impl;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Reference;
import com.enjoyor.soa.traffic.api.dto.tpcms.PassApplyDto;
import com.enjoyor.soa.traffic.api.dto.tpcms.PassVehicleDto;
import com.enjoyor.soa.traffic.api.dto.tpcms.PassVehicleFileDto;
import com.enjoyor.soa.traffic.core.tpcms.domain.PassApply;
import com.enjoyor.soa.traffic.core.tpcms.domain.PassVehicle;
import com.enjoyor.soa.traffic.core.tpcms.domain.PassVehicleFile;
import com.enjoyor.soa.traffic.core.tpcms.domain.RltApplyZone;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IPassApplyMapper;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IPassCheckMapper;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IPassVehicleFileMapper;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IPassVehicleMapper;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IRltApplyZoneMapper;
import com.enjoyor.soa.traffic.core.tpcms.service.IPassApplyService;
import com.enjoyor.soa.traffic.frame.logger.IPubLogMapper;
import com.enjoyor.soa.traffic.process.service.ProcessService;
import com.enjoyor.soa.traffic.process.vo.ProcessVo;
import com.enjoyor.soa.traffic.util.enums.EnumApplyStatus;
import com.enjoyor.soa.traffic.util.enums.log.LogInfoDic;
import com.enjoyor.soa.traffic.util.helper.ReflectHelper;
import com.enjoyor.soa.traffic.util.helper.TimeHelper;
import com.enjoyor.soa.traffic.util.pojo.Page;

/**
 * 申请单信息
 * 
 * @author fzj 2018年5月2日
 */
@Service
@Transactional
public class PassApplyService implements IPassApplyService {

    @Autowired
    private IPassApplyMapper passApplyMapper;

    @Autowired
    private IPassVehicleMapper passVehicleMapper;

    @Autowired
    private IPassVehicleFileMapper passVehicleFileMapper;

    @Autowired
    private IRltApplyZoneMapper rltApplyZoneMapper;

    @Reference(timeout = 3000)
    private ProcessService dubboProcessService;

    @Value("${process.modal.id}")
    private String processDefinitionKey;

    @Autowired
    private IPubLogMapper pubLogMapper;

    @Autowired
    private IPassCheckMapper passCheckMapper;

    @Value("${log.system.name}")
    private String systemName;

    /**
     * 新增申请单信息
     */
    @SuppressWarnings("unused")
    @Override
    public String insertPassApply(PassApplyDto passApplyDto, String userName) {
        // 默认申请信息
        String passApplyId = "A" + TimeHelper.getUniqueString();
        passApplyDto.setPassApplyId(passApplyId);
        passApplyDto.setIsDelete("0");
        passApplyDto.setApplyStatusId(EnumApplyStatus.WAITSUBMIT.getKey());
        passApplyDto.setApplyStatusName(EnumApplyStatus.WAITSUBMIT.getValue());
        passApplyDto.setApplyTime(TimeHelper.dateToLongString());
        passApplyDto.setUpdateTime(TimeHelper.dateToLongString());
        // 新增区域基础信息表
        PassApply passApplyPojo = ReflectHelper.beanToBean(passApplyDto, PassApply.class);
        passApplyMapper.insert(passApplyPojo);
        // 新增申请车辆列表
        List<PassVehicleDto> passVehicleDtoList = passApplyDto.getApplyVehicleList();
        for (PassVehicleDto passVehicleDto : passVehicleDtoList) {
            PassVehicle passVehicle = ReflectHelper.beanToBean(passVehicleDto, PassVehicle.class);
            String applyVehicleId = "V" + TimeHelper.getUniqueString();
            passVehicle.setApplyVehicleId(applyVehicleId);
            passVehicle.setPassApplyId(passApplyId);
            passVehicleMapper.insert(passVehicle);
            // 新增车辆图片
            List<PassVehicleFile> vehicleFileList = ReflectHelper.listToList(passVehicleDto.getVehicleFiles(),
                    PassVehicleFile.class);
            for (PassVehicleFile vehicleFile : vehicleFileList) {
                vehicleFile.setFileId(TimeHelper.getUniqueString());
                vehicleFile.setApplyVehicleId(applyVehicleId);
                passVehicleFileMapper.insert(vehicleFile);
            }
        }
        // 新增关联申请区域列表
        String applyZoneIds = passApplyDto.getApplyZoneIds();
        String applyZoneNames = passApplyDto.getApplyZoneNames();
        if (applyZoneIds != null && applyZoneNames != null && !"".equals(applyZoneIds) && !"".equals(applyZoneNames)) {
            String[] applyZoneIdArr = applyZoneIds.replaceAll(" ", "").split(";");
            String[] applyZoneNameArr = applyZoneNames.replaceAll(" ", "").split(";");
            if (applyZoneIdArr.length == applyZoneNameArr.length) {
                for (int i = 0; i < applyZoneIdArr.length; i++) {
                    RltApplyZone rltApplyZone = new RltApplyZone();
                    rltApplyZone.setRltId(TimeHelper.getUniqueString());
                    rltApplyZone.setPassApplyId(passApplyId);
                    rltApplyZone.setApplyZoneId(applyZoneIdArr[i]);
                    rltApplyZone.setApplyZoneName(applyZoneNameArr[i]);
                    rltApplyZoneMapper.insert(rltApplyZone);
                }
            }
        }
        // 保存日志
        pubLogMapper.saveNoramlLogInfo(userName, systemName, LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_INSERT.getCode(),
                String.format("新增申请单编号:{%s} 操作成功!", new Object[] { passApplyId }),
                LogInfoDic.LOG_MODULAR_ENUM.PROCESS_MANAGEMENT.getMessage());

        // 启动流程引擎
        String processStart = this.startProcess(passApplyId);
        return passApplyId;
    }

    /**
     * 删除申请单信息
     */
    @SuppressWarnings("unused")
    @Override
    public int deletePassApply(String passApplyId, String userName) {
        PassApply passApplyPojo = new PassApply();
        passApplyPojo.setPassApplyId(passApplyId);
        passApplyPojo.setIsDelete("1");
        passApplyPojo.setUpdateTime(TimeHelper.dateToLongString());
        int deleteNum = passApplyMapper.updateByIdSelective(passApplyPojo);
        // 保存日志
        pubLogMapper.saveNoramlLogInfo(userName, systemName, LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_DELETE.getCode(),
                String.format("删除申请单编号:{%s} 操作成功!", new Object[] { passApplyPojo.getPassApplyId() }),
                LogInfoDic.LOG_MODULAR_ENUM.PROCESS_MANAGEMENT.getMessage());
        // 执行流程引擎失效
        ProcessVo processVo = this.submitProcess(passApplyId, "admin", "0");
        return deleteNum;
    }

    /**
     * 修改申请单信息
     */
    @Override
    public int editPassApply(PassApplyDto passApplyDto, String userName) {
        // 修改申请信息表
        PassApply passApplyPojo = ReflectHelper.beanToBean(passApplyDto, PassApply.class);
        passApplyPojo.setUpdateTime(TimeHelper.dateToLongString());
        int updateNum = passApplyMapper.updateByIdSelective(passApplyPojo);
        // 删除申请车辆以及图片的旧数据
        PassVehicle passVehicleSea = new PassVehicle();
        Map<String, Object> apllyIdMap = new HashMap<String, Object>();
        String passApplyId = passApplyDto.getPassApplyId();
        apllyIdMap.put("passApplyId", passApplyId);
        passVehicleSea.setPassApplyId(passApplyPojo.getPassApplyId());
        List<PassVehicle> oldVehicleList = passVehicleMapper.getVehicleList(apllyIdMap);
        for (PassVehicle passVehicle : oldVehicleList) {
            String applyVehicleId = passVehicle.getApplyVehicleId();
            passVehicleFileMapper.deleteFileByVehicleId(applyVehicleId);
            passVehicleMapper.deleteById(applyVehicleId);
        }
        // 删除关联区域数据
        rltApplyZoneMapper.deleteRltByApplyId(passApplyId);

        // 新增申请车辆列表
        List<PassVehicleDto> passVehicleDtoList = passApplyDto.getApplyVehicleList();
        for (PassVehicleDto passVehicleDto : passVehicleDtoList) {
            PassVehicle passVehicle = ReflectHelper.beanToBean(passVehicleDto, PassVehicle.class);
            String applyVehicleId = "V" + TimeHelper.getUniqueString();
            passVehicle.setApplyVehicleId(applyVehicleId);
            passVehicle.setPassApplyId(passApplyId);
            passVehicleMapper.insert(passVehicle);
            // 新增车辆图片
            List<PassVehicleFile> vehicleFileList = ReflectHelper.listToList(passVehicleDto.getVehicleFiles(),
                    PassVehicleFile.class);
            for (PassVehicleFile vehicleFile : vehicleFileList) {
                vehicleFile.setFileId(TimeHelper.getUniqueString());
                vehicleFile.setApplyVehicleId(applyVehicleId);
                passVehicleFileMapper.insert(vehicleFile);
            }
        }
        // 新增关联申请区域列表
        String applyZoneIds = passApplyDto.getApplyZoneIds();
        String applyZoneNames = passApplyDto.getApplyZoneNames();
        if (applyZoneIds != null && applyZoneNames != null && !"".equals(applyZoneIds) && !"".equals(applyZoneNames)) {
            String[] applyZoneIdArr = applyZoneIds.replaceAll(" ", "").split(";");
            String[] applyZoneNameArr = applyZoneNames.replaceAll(" ", "").split(";");
            if (applyZoneIdArr.length == applyZoneNameArr.length) {
                for (int i = 0; i < applyZoneIdArr.length; i++) {
                    RltApplyZone rltApplyZone = new RltApplyZone();
                    rltApplyZone.setRltId(TimeHelper.getUniqueString());
                    rltApplyZone.setPassApplyId(passApplyId);
                    rltApplyZone.setApplyZoneId(applyZoneIdArr[i]);
                    rltApplyZone.setApplyZoneName(applyZoneNameArr[i]);
                    rltApplyZoneMapper.insert(rltApplyZone);
                }
            }
        }
        // 保存日志
        pubLogMapper.saveNoramlLogInfo(userName, systemName, LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_UPDATE.getCode(),
                String.format("修改申请单编号:{%s} 操作成功!", new Object[] { passApplyPojo.getPassApplyId() }),
                LogInfoDic.LOG_MODULAR_ENUM.PROCESS_MANAGEMENT.getMessage());
        return updateNum;
    }

    /**
     * 修改申请单状态
     */
    @SuppressWarnings("unused")
    @Override
    public int editPassApplyStatus(String passApplyId, String applyStatusId, String userName) {
        // 修改申请信息表
        PassApply passApplyPojo = new PassApply();
        passApplyPojo.setPassApplyId(passApplyId);
        passApplyPojo.setUpdateTime(TimeHelper.dateToLongString());
        if (EnumApplyStatus.WAITSUBMIT.getKey().equals(applyStatusId)) {
            passApplyPojo.setApplyStatusId(applyStatusId);
            passApplyPojo.setApplyStatusName(EnumApplyStatus.WAITSUBMIT.getValue());
        } else if (EnumApplyStatus.WAITCHECK.getKey().equals(applyStatusId)) {
            // 提交审核
            passApplyPojo.setApplyStatusId(applyStatusId);
            passApplyPojo.setApplyStatusName(EnumApplyStatus.WAITCHECK.getValue());
            // 删除以前的审核记录（假删除）
            int deleteNum = passCheckMapper.updateByApplyId(passApplyId);
            // 执行流程引擎提交
            ProcessVo processVo = this.submitProcess(passApplyId, "admin", "1");
        } else if (EnumApplyStatus.CHECKPASS.getKey().equals(applyStatusId)) {
            passApplyPojo.setApplyStatusId(applyStatusId);
            passApplyPojo.setApplyStatusName(EnumApplyStatus.CHECKPASS.getValue());
        } else if (EnumApplyStatus.CHECKREJECT.getKey().equals(applyStatusId)) {
            passApplyPojo.setApplyStatusId(applyStatusId);
            passApplyPojo.setApplyStatusName(EnumApplyStatus.CHECKREJECT.getValue());
        } else if (EnumApplyStatus.CHECKOVERDUE.getKey().equals(applyStatusId)) {
            passApplyPojo.setApplyStatusId(applyStatusId);
            passApplyPojo.setApplyStatusName(EnumApplyStatus.CHECKOVERDUE.getValue());
        }
        int updateNum = passApplyMapper.updateByIdSelective(passApplyPojo);
        // 保存日志
        pubLogMapper.saveNoramlLogInfo(userName, systemName, LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_UPDATE.getCode(),
                String.format("修改申请单编号:{%s} 操作成功!", new Object[] { passApplyPojo.getPassApplyId() }),
                LogInfoDic.LOG_MODULAR_ENUM.PROCESS_MANAGEMENT.getMessage());
        return updateNum;
    }

    /**
     * 获取申请单列表信息
     */
    @Override
    public List<PassApplyDto> getPassApplyList(Map<String, Object> map) {
        // 获取申请单基础信息
        List<PassApply> passApplyList = passApplyMapper.getPassApplyList(map);
        List<PassApplyDto> passApplyDtoList = ReflectHelper.listToList(passApplyList, PassApplyDto.class);
        for (PassApplyDto passApplyDto : passApplyDtoList) {
            // 获取失效时间
            /*String takeEffectDate = passApplyDto.getTakeEffectDate();
            String loseEffectDate = passApplyDto.getLoseEffectDate();
            int addMonth = 0;
            if ("APPLYTYPE01".equals(passApplyDto.getApplyTypeId())) {
                addMonth = 1;
            } else if ("APPLYTYPE02".equals(passApplyDto.getApplyTypeId())) {
                addMonth = 3;
            } else if ("APPLYTYPE03".equals(passApplyDto.getApplyTypeId())) {
                addMonth = 12;
            }
            try {
                Date takeDate = TimeHelper.StringToDate(takeEffectDate, "yyyy-MM-dd");
                Date loseDate = TimeHelper.addMonth(takeDate, addMonth);
                loseEffectDate = TimeHelper.dateToString(loseDate, "yyyy-MM-dd");
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            passApplyDto.setLoseEffectDate(loseEffectDate);*/

            Map<String, Object> apllyIdMap = new HashMap<String, Object>();
            String passApplyId = passApplyDto.getPassApplyId();
            apllyIdMap.put("passApplyId", passApplyId);
            // 获取申请单关联区域信息
            String applyZoneIds = "";
            String applyZoneNames = "";
            List<RltApplyZone> rltApplyZoneList = rltApplyZoneMapper.getRltApplyZoneList(apllyIdMap);
            for (RltApplyZone rltApplyZone : rltApplyZoneList) {
                if (rltApplyZone.getApplyZoneId() != null && !"".equals(rltApplyZone.getApplyZoneId())) {
                    applyZoneIds += rltApplyZone.getApplyZoneId() + ";";
                }
                if (rltApplyZone.getApplyZoneName() != null && !"".equals(rltApplyZone.getApplyZoneName())) {
                    applyZoneNames += rltApplyZone.getApplyZoneName() + ";";
                }
            }
            applyZoneIds = applyZoneIds.substring(0, applyZoneIds.length() - 1);
            applyZoneNames = applyZoneNames.substring(0, applyZoneNames.length() - 1);
            passApplyDto.setApplyZoneIds(applyZoneIds);
            passApplyDto.setApplyZoneNames(applyZoneNames);
            // 获取申请车辆以及对应图片信息
            List<PassVehicle> passVehicleList = passVehicleMapper.getVehicleList(apllyIdMap);
            List<PassVehicleDto> passVehicleDtoList = ReflectHelper.listToList(passVehicleList, PassVehicleDto.class);
            for (PassVehicleDto passVehicleDto : passVehicleDtoList) {
                Map<String, Object> vehicleIdMap = new HashMap<String, Object>();
                String applyVehicleId = passVehicleDto.getApplyVehicleId();
                vehicleIdMap.put("applyVehicleId", applyVehicleId);
                List<PassVehicleFileDto> vehicleFileList = ReflectHelper
                        .listToList(passVehicleFileMapper.getFileList(vehicleIdMap), PassVehicleFileDto.class);
                passVehicleDto.setVehicleFiles(vehicleFileList);
            }
            passApplyDto.setApplyVehicleList(passVehicleDtoList);
        }
        return passApplyDtoList;
    }

    /**
     * 获取申请单分页信息
     */
    @SuppressWarnings("rawtypes")
    @Override
    public Page getPassApplyPage(Page page) {
        return passApplyMapper.selectPageInfo(page);
    }

    /**
     * 启动流程引擎
     * 
     * @param passApplyId
     *            申请编号
     * @param userId
     *            操作用户ID
     * @param processDefinitionKey
     *            流程模板id
     */
    public String startProcess(String passApplyId) {
        String userId_key = "userid";
        String userId = "admin"; // 启动流程引擎不限制权限统一使用admin
        String processStart = dubboProcessService.start(userId_key, userId, passApplyId, processDefinitionKey);
        return processStart;
    }

    /**
     * 提交流程引擎操作,返回执行后的节点位置
     * 
     * @param passApplyId
     *            申请编号
     * @param userType
     *            提交用户类型 (detachment:支队 ;department:秩序科; leader:领导)
     * @param value
     *            条件参数 值 1，为通过 0，不通过
     * @return ProcessVo 返回当前节点， 任务id、任务标识 、任务名称、任务负责人，业务数据id
     */
    public ProcessVo submitProcess(String passApplyId, String userType, String value) {
        try {
            ProcessVo processVo = dubboProcessService.submitByBuskey_p(passApplyId, userType, "operation", value);
            return processVo;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
    }

}
